<template>
  <div class="admin_box" id="admin_box">
    <div class="b_top">
      <TopMenu/>
    </div>
    <div class="b_bot">
      <div class="menu">
        <el-menu
            class="my_el_menu"
            :collapse="menuState"
            :default-active="thisMenu"
            :active="thisMenu"
            @select="menuClick"
            background-color="#334157"
            text-color="#fff"
            active-text-color="#ffd04b">
          <TreeMenu :data="menuTree"/>
        </el-menu>
      </div>
      <div class="view_main scroll-bar" id="view_main">
        <el-tabs
            v-model="thisMenu"
            type="card"
            @contextmenu.prevent.native="openContextMenu"
            id="menuTab"
            @tab-remove="removeTab">
          <el-tab-pane
              v-for="item in openMenu"
              :closable="item.id !== '-1'"
              :key="item.id"
              :label="item.name"
              :name="item.id"
          />
        </el-tabs>
        <div class="view" id="view">
          <router-view v-slot="{ Component }">
            <keep-alive v-if="$route.meta.keepAlive">
              <component :is="Component" class="router" />
            </keep-alive>
            <component :is="Component" v-else class="router" />
          </router-view>
        </div>
      </div>
    </div>
    <TopRightTab ref="rightTab" v-bind="rightTab"/>
  </div>
</template>

<script setup>
import elementResizeDetectorMaker from 'element-resize-detector'
import TreeMenu from '@/components/menu/tree_menu.vue'
import TopMenu from '@/components/topMenu/index.vue'
import TopRightTab from '@/components/rightTab/topMenu.vue'

const util = inject("util")
const config = inject("config")

const store = useStore()
const router = useRouter()
const route = useRoute()


//定义顶部菜单ref
const rightTab = ref(null);

// const rightTab = reactive({show: false, top: 0, left: 0, menu: null})

const menuTree = util.getSession(config.sessionKey.SYS_MENU_TREE)
const menuState = ref(util.getSession(config.sessionKey.MENU_STATE) || false)

//设置菜单状态
const setMenuState = val => {
  menuState.value = val
}

// 注入到子组件
provide('menuState', menuState)
provide('setMenuState', setMenuState)


const openUrl = ref(config.HOME_PAGE.path)
const menuList = ref([])

const openMenu = computed(() => store.state.menuTab.openMenu)
const thisMenu = computed({
  get: () => store.state.menuTab.thisMenu,
  set: (val) => store.commit('menuTab/setThisMenu', val)
})

watch(menuState, (val) => {
  util.setSession(config.sessionKey.MENU_STATE, val)
})

watch(route, (val) => {
  if (config.HOME_PAGE.path === val.path) {
    menuClick(config.HOME_PAGE.id)
  } else {
    const menu = menuList.value.find((x) => x.path === val.path)
    if (menu) menuClick(menu.id)
  }
})

watch(thisMenu, (val) => {
  const selected = openMenu.value.find((x) => x.id === val)
  if (route.path !== selected?.path) {
    openUrl.value = selected.path
    router.push(openUrl.value)
  }
})


/**
 * 展开菜单树
 * @param tree
 */
const traverseMenuTree = tree => {
  tree.forEach((item) => {
    menuList.value.push(item)
  })
}

/**
 * 遍数树
 * @param list
 * @param id
 * @returns {*|null}
 */
const traverseTreeMenu = (list, id) => {
  for (const item of list) {
    if (item.children?.length) {
      const found = traverseTreeMenu(item.children, id)
      if (found) return found
    }
    if (item.id === id) return item
  }
  return null
}

const menuClick = key => {
  store.commit('menuTab/setThisMenu', key)
  if (!openMenu.value.some((x) => x.id === key)) {
    const menu = traverseTreeMenu(menuTree, key)
    if (menu) {
      store.commit('menuTab/addOpenMenu', menu)
    }
  }
}

/**
 * 顶部菜单工具条弹出
 * @param e
 */
const openContextMenu = e => {
  const obj = e.target
  const id = obj?.id?.split('tab-')[1]
  if (id === thisMenu.value) {
    const menu = openMenu.value.find((x) => x.id === id)
    let left = e.clientX
    let top = e.clientY + 10
    rightTab.value.openDia(menu, {left, top});
  }
}

/**
 * 移除tab
 * @param delKey
 */
const removeTab = delKey => {
  //找到当前菜单下标
  const delIndex = openMenu.value.findIndex((x) => x.id === delKey)
  //删除vuex的菜单
  store.commit('menuTab/delOpenMenu', delKey)
  //判断删除的菜单是否等于当前选中的
  if (delKey === thisMenu.value) {
    const fallback = delIndex >= openMenu.value.length
        ? openMenu.value.at(-1)?.id
        : openMenu.value[delIndex]?.id
    //切换菜单
    if (fallback) {
      store.commit('menuTab/setThisMenu', fallback)
    }
  }
}

/**
 * 初始化页面大小
 */
const initDom = () => {
  const viewMain = document.getElementById('view_main')?.offsetHeight || 0
  const menuTab = document.getElementById('menuTab')?.offsetHeight || 0
  const view = document.getElementById('view')
  if (view) view.style.height = `${viewMain - menuTab - 50}px`
}

onMounted(() => {
  traverseMenuTree(menuTree)
  nextTick(() => {
    initDom()
    elementResizeDetectorMaker().listenTo(document.getElementById('admin_box'), () => {
      nextTick(() => initDom())
    })
  })
})
</script>

<style scoped lang="scss">
.admin_box {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;

  .b_top {
    width: 100%;
    display: flex;
    color: white;
  }

  .b_bot {
    flex: 1;
    width: 100%;
    display: flex;

    .menu {
      height: 100%;
      background-color: #334157;

      :deep(.my_el_menu:not(.el-menu--collapse)) {
        width: 200px;
        height: 100% !important;
      }

      .my_el_menu {
        border: 0px !important;
      }
    }

    .view_main {
      height: 100%;
      flex: 1;
      display: flex;
      flex-direction: column;

      .view {
        width: 99%;
        margin: 0 auto;
        overflow-y: auto;
        overflow-x: hidden;

        .router {
          width: 99%;
          height: 100%;
          margin: 0 auto;
        }
      }
    }
  }
}
</style>
